#ifndef MPHTTPREQUESTMESSAGE_H
#define MPHTTPREQUESTMESSAGE_H

/******************************
 *
 * 名   称：   HttpRequestMessage请求类
 * 用   途：   定义Http请求相关的属性 [ 请求方法、请求地址、请求头、请求体和SSL设置 ] 与方法 [ 生成用于HTTP请求的BUFFER ]。
 * 作用范围：   公共的
 * 创建时间：   2022-10-03
 * 备   注：   1. 代码中包括 HttpRequestContent 请求体的相关定义。HttpRequestContent 与 HttpRequestMessage 属于聚合关系，
 *            2. HttpRequestContent 具有 HttpRequestStringContent、HttpRequestFileContent和HttpRequestFileContent三个派生类，分别对应请求体内容为字符串、文件以及表单的三种情况。
 *            3. HttpRequestMessage请求类和HttpRequestContent及其派生类建议均通过代码中定义的CreateXXXX相关函数创建，不要自行实例化
 * 参考：
 * https://cloud.tencent.com/developer/article/1710875
 *
 ******************************/

#include <memory>
#include <string>

#include "boost/asio/buffer.hpp"

#include "mpHttpDefines.h"
#include "mpUrl.h"
#include "mpHttpHeaders.h"
#include "mpHttpMethod.h"

namespace MP{
namespace HTTP{

/*****************************************
 * HttpRequestContent
 *****************************************/

class HttpRequestContent
{
public:
    using ptr_s = std::shared_ptr<HttpRequestContent>;
    virtual ~HttpRequestContent() = default;
public:
    //设置ContentType
    virtual void setContentType(const std::string & content_type);
    //获取ContentType
    virtual const std::string& getContentType() const;

    //获取MD5值
    virtual std::string getMd5() = 0;
    //获取Body大小
    virtual std::size_t getContentLength() = 0;
    //开始数据写入（如果返回Fasle表示数据存在异常）
    virtual bool beginWriteData() = 0;
    //写入部分数据
    virtual bool onWriteDataSome(std::vector<boost::asio::const_buffer>& buffers) = 0;
    //结束数据写入
    virtual void endWriteData() = 0;

private:
    std::string _httpcontent_type;        //数据类型
};  //HttpRequestContent


/*****************************************
 * HttpRequestMultipartContent
 *****************************************/
class HttpRequestMultipartContent : public HttpRequestContent
{
public:
    using ptr_s = std::shared_ptr<HttpRequestMultipartContent>;
    virtual ~HttpRequestMultipartContent() = default;
public:
    virtual void addFormData(const std::string & key, const std::string & val)  = 0;
    virtual void clearFormDatas()  = 0;
    virtual void addFormFile(const std::string & name,
                             const std::string & fileName,
                             const std::string & filePath)  = 0;
    virtual void clearFormFiles() = 0;
    virtual const std::string& getBoundary() const  = 0;
};





/*****************************************
 * HttpRequestMessage
 *****************************************/

class HttpRequestMessage
{
public:
    using ptr_s = std::shared_ptr<HttpRequestMessage>;
    virtual ~HttpRequestMessage() = default;
public:
    //获取或设置HTTP_METHOD
    virtual const std::string& getHttpMethod() const = 0;
    virtual void setHttpMethod(MP::HTTP::HTTP_METHOD httpMethod) = 0;
    //获取URL相关信息
    virtual const std::string& getScheme() const = 0;
    virtual const std::string& getHost() const = 0;
    virtual unsigned short getPort() const = 0;
    virtual const std::string& getRelativeUri() const = 0;
    //获取或设置HttpRequestHeaders
    virtual HttpRequestHeaders& getHttpRequestHeaders() = 0;
    //获取或设置SSL信息
    virtual SslSettings& getSslSettings() = 0;
    //获取或设置请求体
    virtual HttpRequestContent::ptr_s getHttpRequestContent() const = 0;
    virtual void setHttpRequestContent(HttpRequestContent::ptr_s requestContent) = 0;
    //生成请求头部Buffer
    virtual void getRequestHeaderBuffers(std::string& buf) = 0;
};  //HttpRequestMessage



/****************************************************
 * HttpRequestMessage && HttpRequestContent Creater
 ***************************************************/

//创建空的HttpRequestContent
HttpRequestContent::ptr_s createHttpRequestEmptyContent();
//创建内容为字符串的HttpRequestContent
//HttpRequestContent::ptr_s createHttpRequestStringContent(const std::string& data);
HttpRequestContent::ptr_s createHttpRequestJsonContent(const std::string& json);
HttpRequestContent::ptr_s createHttpRequestXmlContent(const std::string& xml);
HttpRequestContent::ptr_s createHttpRequestFormContent(const std::string& form);
HttpRequestContent::ptr_s createHttpRequestStringContent(const std::string& data,
                                                         const std::string & httpcontent_type);

//创建内容为文件的HttpRequestContent
HttpRequestContent::ptr_s createHttpRequestFileContent(const std::string& filePath);
HttpRequestContent::ptr_s createHttpRequestFileContent(const std::string& filePath,
                                                       const std::string & httpcontent_type);

HttpRequestContent::ptr_s createHttpRequestFileContent(const std::string& filePath,
                                                       std::size_t fileOffset,
                                                       std::size_t sendContentSize);
HttpRequestContent::ptr_s createHttpRequestFileContent(const std::string& filePath,
                                                       std::size_t fileOffset,
                                                       std::size_t sendContentSize,
                                                       const std::string & httpcontent_type);
//创建内容为Form表单的HttpRequestContent
HttpRequestMultipartContent::ptr_s createHttpRequestMultipartContent();
HttpRequestMultipartContent::ptr_s createHttpRequestMultipartContent(const std::string& boundary);

//创建HttpRequestMessage
HttpRequestMessage::ptr_s createHttpRequestMessage(const std::string & uri,
                                                   MP::HTTP::HTTP_METHOD httpMethod);
HttpRequestMessage::ptr_s createHttpRequestMessage(const Url& uri,
                                                   MP::HTTP::HTTP_METHOD httpMethod);
HttpRequestMessage::ptr_s createHttpRequestMessage(const Url& baseAddress,
                                                   const std::string & relativeUri,
                                                   MP::HTTP::HTTP_METHOD httpMethod);

}   //HTTP
}   //MP




#endif // MPHTTPREQUESTMESSAGE_H
